;{ class Damnsingle {

	constructor (options = '' ) {
		let me = this;
		if (options ) {
			this.onRouter = [];
			this.public = {};
			this.options = options;
			this.mainView = {
				ID : options.mainViewId , 
				DOM : document.getElementById(options.mainViewId)
			}
			if (this.options.init){
				window.onload = function() {
				　　me.options.init.call(); 
				}
			}
			if ( options.relys.length != 0 ) {
				options.relys.forEach(function (i) {
					let tClass = window[`Damnsingle_${i}`]; 
					for(let key in tClass) {
						Damnsingle.prototype[key] = tClass[key];
					}
					Damnsingle.prototype.__con.call(me);  
					Damnsingle.prototype.__con = undefined;
				});
			}
		} else {
			throw new Error("'options' is not defined");
		}
	}

	controller (controllers = '') {
		this._controllers = controllers;  
		this._listenInRouter(); 
	}

	T (options = {}) { 
		let me = this;
		let src = this.http("get",{
			url : this.options.defaultTemplatesDir + "/" + options.template + ".html" ,
    		data: {} 
		});
		document.getElementById(options.containerId).innerHTML = src;
		let containerChild = document.querySelectorAll("*[ds-ajaxget]"); 
		let ds = [];
		containerChild.forEach(function (obj){
		ds['ajaxget'] = obj.getAttribute("ds-ajaxget"); 
		if ( ds['ajaxget'] ) {
			let tCodes = obj.outerHTML;
			let dataObj = me.http("get",{
				url : ds['ajaxget'].split("||")[0] ,
    			data: options[ds['ajaxget'].split("||")[1]]
			}); 
			dataObj = JSON.parse(dataObj); 
			let variables = tCodes.split("{{ ");
			let newCode = "";  
			if ( returnType(dataObj) == "Array" ) { 
				dataObj.forEach(function (dataO) { 
					newCode = newCode + tCodes;
					for (var i = 1; i < variables.length; i++) {  
						newCode = newCode.replaceAll("{{ "+variables[i].split(" }}")[0]+" }}" , dataO[variables[i].split(" }}")[0]]).replace("ds-ajaxget=\""+ds['ajaxget']+"\"" , "");
					}
				}); 
			} else if ( returnType(dataObj) == "Object" ) {
				newCode = newCode + tCodes;
				for (var i = 1; i < variables.length; i++) {  
					newCode = newCode.replaceAll("{{ "+variables[i].split(" }}")[0]+" }}" , dataObj[variables[i].split(" }}")[0]]).replace("ds-ajaxget=\""+ds['ajaxget']+"\"" , "");
				}
		    } 
			obj.outerHTML = newCode; 
		}
		});
		options.complete();
	}

	redirect (str) {
		window.location.href = location.pathname + "#" + str;
	}

	_ajax (options = {}) { 
 
	    options.data=options.data||{};  
	    options.type=options.type||'get';  
	    options.timeout=options.timeout||0;   
	    //整理data数据  
	    options.data.t = Math.random();//给data创建一个t键   
	    let arr=[];  
	    for(let key in options.data) {  
	        arr.push(key+'='+encodeURIComponent(options.data[key]));      
	    }  
	    let str = arr.join('&');   
	    let oAjax = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');    
	   
	    let timer = null;
	    if( options.timeout ) {  
	        timer = setTimeout(function(){  
	           options.error('timeout');
	           oAjax.abort();  //终止加载    
	        },options.timeout);  
	    }

	    oAjax.onreadystatechange = function() {//4  
	        if(oAjax.readyState==4){  
	            if(oAjax.status>=200 && oAjax.status<300 || oAjax.status==304){  
	                clearInterval(timer);  
	                options.success && options.success(oAjax.responseText)  
	            }else{  
	                options.error && options.error(oAjax.status);  
	            }  
	        }
	    }; 
	    if(options.type == 'get') {  
	        oAjax.open('get',options.url+'?'+str, false);//2   
	        oAjax.send();//3  
	    } else {//post  
	        oAjax.open('post',options.url, false);   
	        //设定ajax的头信息  
	        oAjax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');   
	        oAjax.send(str); 
	    }   
	}

	_listenInRouter () {
		let me = this;
		if ( me.options.isRouteTracking ) me._analyticalRouter.call(me);
		window.onhashchange = function() {
			me.onRouter.forEach(function (fn){
				fn.call(me);
			});
			me._analyticalRouter.call(me);
		}
	}

	_analyticalRouter() {  
		let routerPath = window.location.hash.substr(1); 
		if ( routerPath == "" && this.options.defaultControllerName ) { 
			routerPath = this.options.defaultControllerName;
		}
		if ( routerPath.indexOf("?") != -1 ) {
			routerPath = routerPath.split("?")[0];
		}

		if ( returnType(this._controllers) === "Object" && this.options ) { 
			routerPath = routerPath.replaceAll("/","().").replaceAll("\/","().") + "()"; 
			eval("this._controllers." + routerPath);
		}
		if ( returnType(this._controllers) === "Array" && this.options ) {
			let controllerName = (routerPath.indexOf("/") != -1) ? routerPath.split("/")[0] : routerPath.split("\/")[0];
			let controller = this._loadControllerSrc(controllerName, true);
			routerPath = routerPath.replaceAll("/","().").replaceAll("\/","().") + "()"; 
			eval("controller." + routerPath);
		}
	}

	_loadControllerSrc(controllerName = '' , isEval = false) {
		let src = '';
		this._ajax({
			url : this.options.defaultControllersDir + "/" + controllerName + ".js" ,
    		data: {}, 
    		type : "get",
	        success:function(str){
	        	src = str;
	        },
	        error:function(errorinfo){
	        	throw new Error("controller have a error : " + errorinfo);
	        }
		});
		return ( isEval === false ) ? src : eval("("+src+")") ;
	}

	} window.Damnsingle = Damnsingle;
	window.String.prototype.replaceAll = function(s1,s2) { 
		return this.replace(new RegExp(s1,"gm"),s2); 
	}
	const returnType = function(obj) { 
		if ( obj.toString() === "[object Object]" ) {
			return "Object";
		} else if ( obj.toString().indexOf(",") != -1 ) {
			return "Array";
		} else {
			return "Unknown";
		}
	}; 
}